package com.mzj.saas.mservice.enterprise.service;

import com.mzj.saas.commons.ApiData;
import com.mzj.saas.commons.ResultBean;
import com.mzj.saas.commons.StatusCode;
import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.mservice.department.entity.Department;
import com.mzj.saas.mservice.department.repository.DepartmentRepository;
import com.mzj.saas.mservice.enterprise.entity.UserStatistics;
import com.mzj.saas.mservice.enterprise.repository.EnterpriseDataRepository;
import com.mzj.saas.mservice.enterprise.vo.DailyDataVo;
import com.mzj.saas.mservice.enterprise.vo.RequestParamVO;
import com.mzj.saas.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class EnterpriseDataService {

    private static final Logger LOG = LoggerFactory.getLogger(EnterpriseDataService.class);

    @Autowired
    private EnterpriseDataRepository enterpriseDataRepository;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private RedisService redisService;
    @Autowired
    private DepartmentRepository departmentRepository;

    public ResultBean<Map<String, Integer>> employeeData(String accessToken) {
        LOG.info("EnterpriseDataService employeeData accessToken={}", accessToken);
        ResultBean resultBean = new ResultBean();
        resultBean.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        resultBean.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                resultBean.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                resultBean.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return resultBean;
            }
            UserStatistics userStatistics = enterpriseDataRepository.findByOrgIdOrderByStatTimeDescLimit(tokenRedisVo.getEnterpriseId());
            if (userStatistics == null) {
                resultBean.setMsg("暂无员工数据！");
                resultBean.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
                return resultBean;
            }
            //当前企业人数
            Integer currentNumber = userStatistics.getTotalNumber();
            //激活人数
            Integer activateNumber = userStatistics.getActivateNumber();
            //未激活人数
            Integer unActivateNumber = currentNumber - activateNumber;
            //离职人数
            Integer dimissionNumber = userStatistics.getDimissionNumber();

            Map<String, Integer> map = new HashMap<>();
            map.put("currentNumber", currentNumber);
            map.put("activateNumber", activateNumber);
            map.put("unActivateNumber", unActivateNumber);
            map.put("dimissionNumber", dimissionNumber);
            resultBean.setResultData(map);
            resultBean.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
            resultBean.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
            return resultBean;
        } catch (Exception e) {

            e.printStackTrace();
            resultBean.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            resultBean.setMsg(StatusCode.ERROR_CODE_10001.getErrorCode());
            return resultBean;

        }
    }


    /**
     * @param
     * @return
     */
    public ResultBean<List<Map<String, Integer>>> enterpriseDailyData(String accessToken) {
        LOG.info("EnterpriseDataService enterpriseDailyData accessToken={}", accessToken);
        ResultBean resultBean = new ResultBean();
        resultBean.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        resultBean.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                resultBean.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                resultBean.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return resultBean;
            }
            //获取请求时候的当天日期
            Date now = DateUtils.parseDate(DateFormatUtils.format(new Date(), "yyyy-MM-dd"), "yyyy-MM-dd");
            //前七天日期
            Date beginDate = DateUtils.addDays(now, -30);
            //后一天日期
            Date endDate = DateUtils.addDays(now, 1);
            StringBuffer dailyDataSql = new StringBuffer(" SELECT user_num AS activateNumber, DATE_FORMAT(stat_date, \"%Y-%m-%d\") AS day FROM day_use_user_num ");
            List<Object> args = new ArrayList<>();
            dailyDataSql.append(" WHERE  dep_id = ? AND stat_date >= ? AND stat_date< ?  ");
            args.add(tokenRedisVo.getEnterpriseId());
            args.add(beginDate);
            args.add(endDate);
            List<DailyDataVo> userStatisticsList = jdbcTemplate.query(dailyDataSql.toString(), args.toArray(), new BeanPropertyRowMapper<>(DailyDataVo.class));
            Map<String, DailyDataVo> userStatisticsMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(userStatisticsList)) {
                for (DailyDataVo u : userStatisticsList) {
                    userStatisticsMap.put(u.getDay(), u);
                }
            }
            List<Map<String, Object>> data = new ArrayList<>();
            List<String> dateRange = generateDateRange(beginDate, endDate);

            for (String d : dateRange) {
                Map map = new HashMap();
                map.put("dateStr", d);
                DailyDataVo userStatistics = userStatisticsMap.get(d);
                if (userStatistics != null) {
                    map.put("activateNumber", userStatistics.getActivateNumber());
                } else {
                    map.put("activateNumber", 0);
                }
                data.add(map);
            }

            resultBean.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
            resultBean.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
            resultBean.setResultData(data);
            return resultBean;
        } catch (Exception e) {
            e.printStackTrace();
            resultBean.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            resultBean.setMsg(StatusCode.ERROR_CODE_10001.getErrorCode());
            return resultBean;

        }
    }

    //得到N天的时间list
    public List<String> generateDateRange(Date beginDate, Date endDate) {
        List<String> list = new ArrayList<>();
        Date date = beginDate;
        while (date.before(endDate)) {
            list.add(DateFormatUtils.format(date, "yyyy-MM-dd"));
            date = DateUtils.addDays(date, 1);
        }
        return list;
    }

    /*
     *查看离职/未激活员工
     */
    public ResultBean<Object> leaveDepartmentPeople(String accessToken, Integer status, Integer pageNumber, Integer pageSize) {
        LOG.info("---EnterpriseDataService leaveDepartmentPeople accessToken={},pageNumber={},pageSize={}", accessToken, pageNumber, pageSize);
        ResultBean<Object> result = new ResultBean<>();
        ApiData<Map<String, Object>> apiData = new ApiData<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            Optional<Department> existDepartment = departmentRepository.findById(tokenRedisVo.getEnterpriseId());
            if (existDepartment == null) {
                return ResultBean.failedResultWithMsg("部门不存在或已删除");
            }
            StringBuffer depIds = new StringBuffer();
            String sql = "SELECT id,`name` FROM ( SELECT t1.id,t1.`name`,IF(FIND_IN_SET(parent_id, @pids) > 0,@pids := CONCAT(@pids, ',', id),0) AS ischild FROM ( SELECT id, parent_id,  `name` FROM `saas_department` t ORDER BY  parent_id,id ) t1,( SELECT @pids := ?) t2 ) t3 WHERE ischild != 0  \n";
            List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, tokenRedisVo.getEnterpriseId());
            maps.forEach(m -> {
                depIds.append(m.get("id")).append(",");
            });
            depIds.append(tokenRedisVo.getEnterpriseId());
            StringBuffer sbSql = new StringBuffer(" SELECT u.`id`,u.`name`,u.`mobile`,u.`leave_date`  AS leaveDate  FROM `saas_user` u INNER JOIN  `saas_user_department_ref` d ON u.id=d.user_id  WHERE 1 = 1 ");
            if (status != null) {
                sbSql.append("  AND  u.status =").append(status);
            }
            if (!StringUtils.isBlank(depIds.toString())) {
                sbSql.append("   AND  d.dep_id   IN  (" + depIds.toString() + ")  ");
            }
            String count="SELECT COUNT(0) FROM ("+sbSql+") c";
            String offsets = "   LIMIT ? OFFSET ? ";
            // 查询总记录数
            Long total = jdbcTemplate.queryForObject(count, Long.class);
            if (total == 0) {
                result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
                result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
                result.setResultData(null);
                return result;
            }
            // 查询分页数据
            List<Object> args = new ArrayList<>();
            sbSql.append(offsets);
            args.add(pageSize);
            args.add(pageNumber * pageSize);
            List<Map<String, Object>> peopleList = jdbcTemplate.queryForList(sbSql.toString(), args.toArray());
            peopleList =  peopleList.stream().distinct().collect(Collectors.toList());
            apiData.setData(peopleList);
            apiData.setTotal(total);
            result.setResultData(apiData);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     * 管理员操作记录
     */
    public ResultBean<Object> managerOperationRecord(String accessToken, Integer pageNumber, Integer pageSize, RequestParamVO filter) {
        LOG.info("---EnterpriseDataService managerOperationRecord accessToken={},pageNumber={},pageSize={},filter={}", accessToken, pageNumber, pageSize, filter);
        ResultBean<Object> result = new ResultBean<>();
        ApiData<Map<String, Object>> apiData = new ApiData<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            Optional<Department> existDepartment = departmentRepository.findById(tokenRedisVo.getEnterpriseId());
            if (existDepartment == null) {
                return ResultBean.failedResultWithMsg("部门不存在或已删除");
            }
            String sql = "SELECT u.`name`,o.`operation_function`  AS `operationFunction`,o.`operation_type` AS `operationType`,o.`detail`,o.`operation_time` AS `operationTime`  FROM `saas_enterprise_operation` o INNER JOIN `saas_user` u ON u.id=o.user_id  WHERE o.type=1  AND org_id=?  \n";
            String offsets = "   LIMIT ? OFFSET ? ";
            List<Object> args = new ArrayList<>();
            args.add(tokenRedisVo.getEnterpriseId());
            StringBuilder where = new StringBuilder();
            if (StringUtils.isNotBlank(filter.getOperationFunction())) {
                where.append("  AND  o.`operation_function` like ?  \n");
                args.add("%" + filter.getOperationFunction() + "%");
            }
            if (StringUtils.isNotBlank(filter.getBeginTime()) && StringUtils.isNotBlank(filter.getEndTime())) {
                where.append("  AND o.operation_time between ? and ? \n");
                args.add(filter.getBeginTime());
                args.add(filter.getEndTime());
            }
            // 查询总记录数
            String count = "select count(1) FROM (" + sql + where + ") c  ";
            Long total = jdbcTemplate.queryForObject(count, Long.class, args.toArray());
            LOG.info("SQL :" + sql + where);
            if (total == 0) {
                result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
                result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
                result.setResultData(null);
                return result;
            }
            // 查询分页数据
            where.append("  ORDER BY ").append(" o.operation_time desc ").append(" \n").append(offsets);
            args.add(pageSize);
            args.add(pageNumber * pageSize);
            List<Map<String, Object>> peopleList = jdbcTemplate.queryForList(sql + where, args.toArray());
            apiData.setData(peopleList);
            apiData.setTotal(total);
            LOG.info("SQL :" + sql + where);
            result.setResultData(apiData);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

}
